package com.atguigu.gmall.item;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.product.model.*;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

@RestController
@RequestMapping("/api/item")
@SuppressWarnings("all")
public class ItemController {
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private Executor executor;
    @Autowired
    private ListFeignClient listFeignClient;
    @GetMapping("/{skuId}")
    public Map<String,Object> getItemAllData(@PathVariable("skuId") Long skuId){
        //0.判断用户访问商品不存在,加了布隆过滤器
        //如果不存在,则是非法访问,直接返回  反之执行远程调用  todo 交付测试前注释放开
        /*RBloomFilter<Long> bloomFilter = redissonClient.getBloomFilter(RedisConst.SKU_BLOOM_FILTER);
        boolean contains = bloomFilter.contains(skuId);
        if (!contains){
            throw  new RuntimeException("访问数据不存在,你龙啊");
        }*/


        Map<String,Object>map = new HashMap<>();
        /**
         * `1.根据skuid查询商品sku基本信息包含图片列表-返回sku商品对象`
         *
         * 获取sku,放在map中
         *
         * `2.根据返回的三级分类的id,来查询所属的三级分类信息`
         *
         *
         *
         * `3.根据skuid查询价格`
         *
         * `4.根据skuid查询商品海报列表`
         *
         * `5.根据skuid来查询平台属性列表`,attrlist
         *
         * `6.根据spuid和skuid查询销售属性,选中当前商品销售属性`saleattrlistcheck
         *
         * `7.根据spuid查询销售属性摩根sku对照关系,,--(选择销售属性组合) 切换sku`  todo: 前端解析的是json字符串
         *
         * 往map放值得时候要,,转成json,JSON.toJSONString();
         * `8. todo 远程调用搜索微服务更新商品热度
         * 都判断为不为空
         */

        //`1.根据skuid查询商品sku基本信息包含图片列表-返回sku商品对象`
        //-- 产生异步任务对象-后续其他任务需要使用返回结果
        CompletableFuture<SkuInfo> skuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            if (skuInfo != null) {
                map.put("skuInfo", skuInfo);

            }
            return  skuInfo;
        }, executor);

        //`2.根据返回的三级分类的id,来查询所属的三级分类信息` -- 当前异步任务对象依赖于其他线程,获取上一个线程返回结果
        CompletableFuture<Void> categorCompletableFuture = skuInfoCompletableFuture.thenAccept((skuInfo) -> {

            BaseCategoryView categoryView = productFeignClient.getCategoryView(skuInfo.getCategory3Id());
            if (categoryView != null) {
                map.put("categoryView", categoryView);
            }
        });
        //`3.根据skuid查询价格`
        CompletableFuture<Void> priceCompletableFuture = CompletableFuture.runAsync(() -> {

            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            if (skuPrice != null) {
                map.put("price", skuPrice);
            }
        }, executor);
        //`4.根据skuid查询商品海报列表`  -- 当前异步任务对象依赖于其他线程,获取上一个线程返回结果
        CompletableFuture<Void> spuPosterListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {

            List<SpuPoster> spuPosterBySpuId = productFeignClient.getSpuPosterBySpuId(skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(spuPosterBySpuId)) {
                map.put("spuPosterList", spuPosterBySpuId);
            }
        });
        //5.根据skuid来查询平台属性列表`,attrlist
        CompletableFuture<Void> skuAttrListCompletableFuture = CompletableFuture.runAsync(() -> {

            List<BaseAttrInfo> attrList = productFeignClient.getAttrList(skuId);
            if (!CollectionUtils.isEmpty(attrList)) {
                map.put("skuAttrList", attrList);
            }
        }, executor);
        //6.根据spuid和skuid查询销售属性,选中当前商品销售属性`saleattrlistcheck
        CompletableFuture<Void> spuSaleAttrListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {

            List<SpuSaleAttr> spuSaleAttrListCheckBySku = productFeignClient.getSpuSaleAttrListCheckBySku(skuId, skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(spuSaleAttrListCheckBySku)) {
                map.put("spuSaleAttrList", spuSaleAttrListCheckBySku);
            }

        }, executor);


        //`7.根据spuid查询销售属性摩根sku对照关系,,--(选择销售属性组合) 切换sku`  todo: 前端解析的是json字符串
        CompletableFuture<Void> valuesSkuJsonCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            Map<String, Object> skuValueIdsMap = productFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
            if (!CollectionUtils.isEmpty(skuValueIdsMap)) {
                map.put("valuesSkuJson", JSON.toJSONString(skuValueIdsMap));
            }
        }, executor);
        //8. todo 远程调用搜索微服务更新商品热度
        CompletableFuture<Void> goodsScoreCompletableFuture = CompletableFuture.runAsync(() -> {
            listFeignClient.incrHotScore(skuId);
        }, executor);

        //等待所有异步任务,执行完毕,主线程继续执行响应结果
        CompletableFuture.allOf(
                skuInfoCompletableFuture,
                categorCompletableFuture,
                priceCompletableFuture,
                spuPosterListCompletableFuture,
                skuAttrListCompletableFuture,
                spuSaleAttrListCompletableFuture,
                valuesSkuJsonCompletableFuture,
                goodsScoreCompletableFuture
        ).join();
        return map;

    }
}
